package cc.rengu.igas.cops.common.util;

import cc.rengu.igas.cops.common.constant.CopsParamConstant;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Security;

/**
 * Des加密工具类
 *
 * @author fuyp
 */
public class DesUtil {
    private static DesUtil des = null;

    /*USED*/
    public static DesUtil getInstance() throws Exception {
        if (des == null) {
            synchronized (CopsParamConstant.ENC_PARA) {
                if (des == null) {
                    des = new DesUtil();
                    Security.addProvider(new com.sun.crypto.provider.SunJCE());
                    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//添加PKCS7Padding支持
                }
            }
        }

        return des;
    }

    /*USED*/
    public byte[] decrypt(byte[] bytE, byte[] key, byte[] ivKey) throws Exception {
        return des(bytE, key, ivKey, Cipher.DECRYPT_MODE);
    }

    /*USED*/
    private byte[] des(byte[] bytP, byte[] key, byte[] ivKey, int mode) throws Exception {
        // 加密算法名称+加密模式+填充模式()
        Cipher cipher = Cipher.getInstance(CopsParamConstant.ENC_PARA);
        if (ivKey != null && ivKey.length != 0) {
            // 设置向量
            IvParameterSpec iv = new IvParameterSpec(ivKey);
            // 设置工作模式为加密模式，给出密钥和向量
            cipher.init(mode, getKey(key), iv);
        } else {
            // 设置工作模式为加密模式，给出密钥和向量
            cipher.init(mode, getKey(key));
        }
        // 加密/解密
        byte[] enc = cipher.doFinal(bytP);
        return enc;
    }

    /**
     * 从指定字符串生成密钥，密钥所需的字节数组长度为8位 不足8位时后面补0，超出8位只取前8位
     *
     * @param arrBTmp 构成该字符串的字节数组
     * @throws Exception
     * @return 生成的密钥
     */
    private SecretKey getKey(byte[] arrBTmp) throws Exception {
        // 生成密钥
        // 设置密钥参数
        DESKeySpec desKeySpec = new DESKeySpec(arrBTmp);
        // 获得密钥工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        // 得到密钥对象
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        return secretKey;
    }
}
